package id.co.shuba.spamobile.task;

import id.co.shuba.spamobile.App;
import id.co.shuba.spamobile.Encryptor;
import id.co.shuba.spamobile.Sessions;
import id.co.shuba.spamobile.data.DSARDB;
import id.co.shuba.spamobile.data.DatabaseHandler;
import id.co.shuba.spamobile.data.MaintenanceVisitDB;
import id.co.shuba.spamobile.data.ProspectDB;
import id.co.shuba.spamobile.data.ProspectProgressDB;
import id.co.shuba.spamobile.model.UserInfo;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.StringWriter;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.xmlpull.v1.XmlSerializer;

import android.app.ProgressDialog;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Debug;
import android.util.Log;
import android.util.Xml;
import android.widget.Toast;

public class SaveXMLTask extends
		AsyncTask<String, Integer, AsyncTaskResult<Void>> {
	private DatabaseHandler _db;
	private ProgressDialog _dialog;
	private UserInfo _user;

	public SaveXMLTask(DatabaseHandler db, ProgressDialog dialog, UserInfo user) {
		_db = db;
		_dialog = dialog;
		_user = user;
	}

	private void writeXml(String fileName) throws Exception {
		/*
		UserInfo user = Sessions.getUser(_dialog.getContext());
		String key = user.getNip();
		String completeKey = key.replace(key,
				key + App.Key.substring(0, 24 - key.length()));		
		
		byte[] keyBytes = completeKey.getBytes();
		byte[] ivBytes = App.IV.getBytes();
		
		SecretKeySpec localSecretKeySpec = new SecretKeySpec(keyBytes, Encryptor.ALGO_AES);
		
	    Cipher localCipher = Cipher.getInstance(Encryptor.ENC_AES);
	    IvParameterSpec ivspec = new IvParameterSpec(ivBytes);
	    localCipher.init(Cipher.ENCRYPT_MODE, localSecretKeySpec, ivspec);

	    CipherOutputStream cos = new CipherOutputStream(new FileOutputStream(fileName), localCipher);*/	    	    
			    	    
		
		//StringWriter writer = new StringWriter();		
		//serializer.setOutput(writer);
		//serializer.setOutput(cos, "UTF-8");
		FileOutputStream fos = null;
		GZIPOutputStream gos = null;
		try {
			fos = new FileOutputStream(fileName);					
			gos = new GZIPOutputStream(fos);		

			XmlSerializer serializer = Xml.newSerializer();
			
			serializer.setOutput(gos, "UTF-8");
			//serializer.setOutput(new FileWriter(fileName));
			serializer.startDocument("UTF-8", true);

			serializer.startTag("", "SPA");
			
			writePipelineData(serializer);
			writeDSARData(serializer);
			writeProspectProgressData(serializer);
			writeMaintenanceVisitData(serializer);
			
			serializer.endTag("", "SPA");

			serializer.endDocument();
			
			gos.flush();
			fos.flush();
			//cos.flush();
			//cos.close();
		} catch (Exception e) {
			throw e;
		} finally {
			try {
				if (gos != null) gos.close();
				if (fos != null) fos.close();				
			} catch (Exception e2) {
				Log.e("SaveXML", "IO Error: " + e2.getMessage());
			}
		}
		
	}

	private void writePipelineData(XmlSerializer serializer) throws Exception {
		ProspectDB prospectDB = new ProspectDB(_db);
		Cursor cursor = prospectDB.getList(_user.getAoCode());

		serializer.startTag("", "TBL_PROSPECT");

		if (cursor.moveToFirst()) {
			do {
				serializer.startTag("", "PROSPECT");

				setStringElement(serializer, cursor, "PROSPECT_ID");
				setStringElement(serializer, cursor, "PROSPECT_NO");
				setStringElement(serializer, cursor, "FULL_NAME");
				setStringElement(serializer, cursor, "JENIS_USAHA");
				setLongElement(serializer, cursor, "RENCANA_PLAFON");
				setStringElement(serializer, cursor, "MOBILE_PHONE");
				setStringElement(serializer, cursor, "OFFICE_PHONE");
				setStringElement(serializer, cursor, "RESIDENTIAL_PHONE");
				setStringElement(serializer, cursor, "KODYA_KAB_BUSINESS");
				setStringElement(serializer, cursor, "KECAMATAN_BUSINESS");
				setStringElement(serializer, cursor, "KELURAHAN_BUSINESS");
				setStringElement(serializer, cursor, "PROSPECT_TYPE");
				setStringElement(serializer, cursor, "DEBTOR_TYPE");
				setStringElement(serializer, cursor, "CHANNELING");
				setStringElement(serializer, cursor, "ZIP_CODE_BUSINESS");
				setStringElement(serializer, cursor, "ADDRESS_BUSINESS");
				setStringElement(serializer, cursor, "EKSTERNAL");
				setStringElement(serializer, cursor, "REFERENSI");							
				setStringElement(serializer, cursor, "AVG_EXPENSE");
				setStringElement(serializer, cursor, "DATE_OF_BIRTH");
				setStringElement(serializer, cursor, "MARITAL_STATUS");
				setStringElement(serializer, cursor, "SPOUSE_NAME");
				setLongElement(serializer, cursor, "JML_TANGGUNGAN");
				setStringElement(serializer, cursor, "PRODUCT_CODE");
				setStringElement(serializer, cursor, "KTP_NO");
				setStringElement(serializer, cursor, "KTP_NAME");				
				setStringElement(serializer, cursor, "ENTRY_BY");
				setStringElement(serializer, cursor, "ENTRY_DATE");
				setStringElement(serializer, cursor, "UPDATE_BY");
				setStringElement(serializer, cursor, "UPDATE_DATE");
				setStringElement(serializer, cursor, "AO_CODE");
				setStringElement(serializer, cursor, "UNIT_CODE");
				setStringElement(serializer, cursor, "PROGRESS_STATUS");
				setStringElement(serializer, cursor, "UM_DECISION");
				setStringElement(serializer, cursor, "UM_DECISION_NOTE");
				setStringElement(serializer, cursor, "UM_DECISION_DATE");
				setStringElement(serializer, cursor, "REPUTASI_DEBITUR");
				setStringElement(serializer, cursor, "CO_ASSIGNED");
				setStringElement(serializer, cursor, "ALTERNATE_FOR");
				setStringElement(serializer, cursor, "NOT_INTERESTED_REASON");
				setStringElement(serializer, cursor, "GU_CLOSE_DEAL");
				setStringElement(serializer, cursor, "UPLOAD_BY");
				setStringElement(serializer, cursor, "UPLOAD_DATE");
				setStringElement(serializer, cursor, "IS_UPLOAD");
				setStringElement(serializer, cursor, "IS_DELETED");				
				
				
				setStringElement(serializer, cursor, "LOAN_NUMBER");
				setLongElement(serializer, cursor, "CIF_NUMBER");
				
				setLongElement(serializer, cursor, "OMZET_1");
				setLongElement(serializer, cursor, "OMZET_2");
				setLongElement(serializer, cursor, "OMZET_3");
				setLongElement(serializer, cursor, "OMZET_4");
				setLongElement(serializer, cursor, "OMZET_5");
				setLongElement(serializer, cursor, "OMZET_6");
				setLongElement(serializer, cursor, "OMZET_7");
				setLongElement(serializer, cursor, "OMZET_8");
				setLongElement(serializer, cursor, "OMZET_9");
				setLongElement(serializer, cursor, "OMZET_10");
				setLongElement(serializer, cursor, "OMZET_11");
				setLongElement(serializer, cursor, "OMZET_12");
				setLongElement(serializer, cursor, "OMZET_AVERAGE");
				
				setStringElement(serializer, cursor, "SOURCE_CODE");
				
				setStringElement(serializer, cursor, "PIPELINE_START_TIME");				
				setStringElement(serializer, cursor, "PIPELINE_FINISH_TIME");				
				setStringElement(serializer, cursor, "PROSPECT_START_TIME");
				setStringElement(serializer, cursor, "PROSPECT_FINISH_TIME");
				
				setStringElement(serializer, cursor, "IS_PIPELINE_KP");
				setStringElement(serializer, cursor, "GU_FUP");
				
				setStringElement(serializer, cursor, "KTP_ADDRESS");
				setStringElement(serializer, cursor, "IS_OFFLINE_ENTRY");
				
				setLongElement(serializer, cursor, "FLAG_FREEZE");
				setStringElement(serializer, cursor, "PLACE_OF_BIRTH");
				setStringElement(serializer, cursor, "NIP");
				setStringElement(serializer, cursor, "KARAKTER");
				
				serializer.endTag("", "PROSPECT");
			} while (cursor.moveToNext());
		}

		serializer.endTag("", "TBL_PROSPECT");

		cursor.close();
	}

	private void writeDSARData(XmlSerializer serializer) throws Exception {
		DSARDB dsarDB = new DSARDB(_db);
		Cursor cursor = dsarDB.getListExpot(_user.getAoCode());

		serializer.startTag("", "TBL_PROSPECT_VISIT");

		if (cursor.moveToFirst()) {
			do {
				serializer.startTag("", "PROSPECT_VISIT");
				
				setStringElement(serializer, cursor, "PROSPECT_ID");
				setLongElement(serializer, cursor, "VISIT_NO");
				setStringElement(serializer, cursor, "DATE_VISIT_PLAN");
				setStringElement(serializer, cursor, "DATE_VISIT_ACTUAL");
				setStringElement(serializer, cursor, "JOIN_FIELD_WORK");
				
				setStringElement(serializer, cursor, "OBJECTIVE_OF_VISIT");
				setStringElement(serializer, cursor, "RESULT_OF_VISIT");
				setStringElement(serializer, cursor, "REMARK");
				setStringElement(serializer, cursor, "ENTRY_BY");
				setStringElement(serializer, cursor, "ENTRY_DATE");
				setStringElement(serializer, cursor, "UPDATE_BY");
				setStringElement(serializer, cursor, "UPDATE_DATE");	
				setStringElement(serializer, cursor, "UPLOAD_BY");
				setStringElement(serializer, cursor, "UPLOAD_DATE");
				setStringElement(serializer, cursor, "IS_UPLOAD");
				setStringElement(serializer, cursor, "IS_DELETED");

				serializer.endTag("", "PROSPECT_VISIT");
			} while (cursor.moveToNext());
		}

		serializer.endTag("", "TBL_PROSPECT_VISIT");

		cursor.close();

	}
	
	private void writeProspectProgressData(XmlSerializer serializer)
			throws Exception {
		ProspectProgressDB progDB = new ProspectProgressDB(_db);
		Cursor cursor = progDB.getListByAoCode(_user.getAoCode());

		serializer.startTag("", "TBL_PROSPECT_PROGRESS");

		if (cursor.moveToFirst()) {
			do {
				serializer.startTag("", "PROSPECT_PROGRESS");

				setStringElement(serializer, cursor, "PROSPECT_ID");
				setStringElement(serializer, cursor, "PROGRESS_STATUS");				
				setStringElement(serializer, cursor, "ENTRY_BY");
				setStringElement(serializer, cursor, "ENTRY_DATE");
				setStringElement(serializer, cursor, "UPDATE_BY");
				setStringElement(serializer, cursor, "UPDATE_DATE");	
				setStringElement(serializer, cursor, "UPLOAD_BY");
				setStringElement(serializer, cursor, "UPLOAD_DATE");
				setStringElement(serializer, cursor, "IS_UPLOAD");				

				serializer.endTag("", "PROSPECT_PROGRESS");
			} while (cursor.moveToNext());
		}

		serializer.endTag("", "TBL_PROSPECT_PROGRESS");

		cursor.close();

	}

	private void writeMaintenanceVisitData(XmlSerializer serializer)
			throws Exception {
		MaintenanceVisitDB dsarDB = new MaintenanceVisitDB(_db);
		Cursor cursor = dsarDB.getListExport(_user.getAoCode());

		serializer.startTag("", "TBL_MAINTENANCE_VISIT");

		if (cursor.moveToFirst()) {
			do {
				serializer.startTag("", "MAINTENANCE_VISIT");

				setStringElement(serializer, cursor, "VISIT_ID");
				setStringElement(serializer, cursor, "AO_CODE");
				setStringElement(serializer, cursor, "UNIT_CODE");
				setStringElement(serializer, cursor, "DATE_VISIT");
				setStringElement(serializer, cursor, "NO_ACCOUNT");
				setStringElement(serializer, cursor, "DEBTOR_NAME");
				setStringElement(serializer, cursor, "OBJECTIVE_OF_VISIT");
				setStringElement(serializer, cursor, "ENTRY_BY");
				setStringElement(serializer, cursor, "ENTRY_DATE");
				setStringElement(serializer, cursor, "UPDATE_BY");
				setStringElement(serializer, cursor, "UPDATE_DATE");	
				setStringElement(serializer, cursor, "UPLOAD_BY");
				setStringElement(serializer, cursor, "UPLOAD_DATE");
				setStringElement(serializer, cursor, "IS_UPLOAD");
				setStringElement(serializer, cursor, "IS_DELETED");

				serializer.endTag("", "MAINTENANCE_VISIT");
			} while (cursor.moveToNext());
		}

		serializer.endTag("", "TBL_MAINTENANCE_VISIT");

		cursor.close();

	}

	private void setStringElement(XmlSerializer serializer, Cursor cursor,
			String column) throws Exception {
		serializer.startTag("", column);
		serializer.text(getString(cursor, column));
		serializer.endTag("", column);
	}

	private void setLongElement(XmlSerializer serializer, Cursor cursor,
			String column) throws Exception {
		serializer.startTag("", column);
		serializer.text(String.valueOf(cursor.getLong(cursor
				.getColumnIndex(column))));
		serializer.endTag("", column);
	}

	private String getString(Cursor curs, String column) {
		String value = curs.getString(curs.getColumnIndex(column));
		return value == null ? "" : value;
	}

	@Override
	protected AsyncTaskResult<Void> doInBackground(String... params) {
		try {
			Thread.sleep(1000);
			/*
			UserInfo user = Sessions.getUser(_dialog.getContext());				
			Encryptor enc = new Encryptor(
					Encryptor.ENC_AES,
					Encryptor.ENC_AES, App.createCompleteKey(user.getEncryptionKey()), App.IV);			
			
			String plainResult = writeXml();
			String encResult = enc.encryptText(plainResult);
			
			FileWriter fw = new FileWriter(new File(params[0]));
			BufferedWriter bw = new BufferedWriter(fw);
			fw.write(plainResult);			  
			bw.close();
			fw.close();*/
			
			writeXml(params[0]);
			
			return new AsyncTaskResult<Void>((Void) null);
		} catch (Exception e) {
			return new AsyncTaskResult<Void>(e);
		}
	}

	@Override
	protected void onPreExecute() {
		super.onPreExecute();

		_dialog.show();
	}

	@Override
	protected void onPostExecute(AsyncTaskResult<Void> result) {
		super.onPostExecute(result);

		String message = result.getError() == null ?
			"Save completed!" :
			result.getError().getMessage();
		
		Toast.makeText(_dialog.getContext(), message, Toast.LENGTH_LONG).show();

		_dialog.dismiss();
	}
}
